本篇同步發布於Blog: [解題] POJ - 2431 Expedition
PKU Online Judge
2431 - Expedition
http://poj.org/problem?id=2431
有一輛車子要開往城鎮,距離為L單位,且車上目前有P單位的燃料。路上會有N(1 <= N <= 10000)間的加油站,每間加油站距離城鎮x單位、並能補充p單位的燃料。車子每行駛1單位的距離就得消耗1單位的燃料,而車子的燃料容量無限大,求車子抵達城鎮時的最少加油次數,如果達不到則輸出-1。
範例輸入是4間加油站,需要在第1家(15 10)和第2家(11 5)加油站加油,才能抵達成鎮。
4
4 4
5 2
11 5
15 10
25 10
2
這題需轉換問題,可以看成是當車子開到某站時,如果行經距離超過燃料箱的油量,則檢查經過的加油站的備用油,先從最大量的油倒進燃料箱,直到超過消耗量或者仍無法滿足消耗量。
最大量的油的儲存方式是使用Priority Queue。
以範例輸入來看:
題目測資會有些陷阱,比如加油站的位置不一定由小到大,需要自己排序。或者加油站的補給量有可能是0.......很好玩的測資。
實作也把城鎮當作最後一家加油站,這樣距離/扣油量的計算才會完整。
難度為Medium
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct Stop{
int dist, amount;
};
bool cmp(const Stop &a, const Stop &b)
{
return a.dist < b.dist;
}
int main() {
int n;
Stop stops[10005];
int L, curAmount;
while(cin >> n){
int ans = 0;
bool notToTown = false;
priority_queue<int, vector<int>, less<int> > q;
for(int i = 0 ; i < n;++i){
cin >> stops[i].dist >> stops[i].amount;
}
cin >> L >> curAmount;
stops[n].dist = 0;
stops[n].amount = 0;
sort(stops, stops + (n+1), cmp);
int curLength = L;
for(int i = n ; i >= 0;--i){
int curDistance = curLength - stops[i].dist;
while(curAmount - curDistance < 0){
if(q.empty()){
notToTown = true;
break;
}else{
curAmount += q.top();
q.pop();
ans++;
}
}
curAmount -= curDistance;
q.push(stops[i].amount);
curLength = stops[i].dist;
}
if(notToTown){
cout << "-1" << endl;
}
else{
cout << ans << endl;
}
}
return 0;
}
https://github.com/u8989332/ProblemSolving/blob/master/PKUOnlineJudge/2400-2499/2431.cpp